package org.example.auth.service.impl;

import org.example.auth.domain.Permission;
import org.example.auth.service.IPermissionScanService;
import org.example.auth.service.IPermissionService;
import org.example.base.annotation.ExamplePermission;
import org.example.base.enums.RequestTypeEnum;
import org.example.base.util.ClassUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;

import java.lang.annotation.Annotation;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.List;
import java.util.Objects;

@Service
public class PermissionScanServiceImpl implements IPermissionScanService {

    @Autowired
    private IPermissionService service;
    @Value("${package-scan.url}")
    private String url;

    @Transactional
    @Override
    public void scan() throws ClassNotFoundException {

        service.deleteAll();
        List<Class>  list= ClassUtils.getAllClassName(url);
        list.forEach(System.out::println);
        for(Class clazz:list){
            ExamplePermission annotation =(ExamplePermission)clazz.getAnnotation(ExamplePermission.class);
            if(annotation!=null){
                Permission parent=new Permission();

                parent.setDescs(annotation.name());
                parent.setName(annotation.desc());
                parent.setSn(clazz.getSimpleName());
                RequestMapping annotation2 = (RequestMapping) clazz.getAnnotation(RequestMapping.class);
                String clazzUrl = annotation2.value()[0];

                parent.setUrl(clazzUrl);
                parent.setParent(null);
                service.insert(parent);

                Method[] methods = clazz.getMethods();
                for (Method s:methods) {
                    System.out.println(s.getName());
                }
                for (Method method:methods) {
                    ExamplePermission annotation1 = method.getAnnotation(ExamplePermission.class);
                    if(annotation1!=null){
                        Permission permission = new Permission();

                        permission.setDescs(annotation1.name());
                        permission.setName(annotation1.desc());
                        permission.setSn(clazz.getSimpleName()+":"+method.getName());

                        String methodUrl=getMethodUrl(method);
                        permission.setUrl(clazzUrl+methodUrl);

                        permission.setParent(parent);
                        service.insert(permission);


                    }

                }

            }

        }


    }

    public String getMethodUrl(Method method){
        String methodUrl="";
        RequestTypeEnum[] requestTypeEnums = RequestTypeEnum.values();
        for ( RequestTypeEnum typeEnum:requestTypeEnums) {
            Annotation annotation = method.getAnnotation(typeEnum.getRequestType());
            if(Objects.isNull(annotation)){
                continue;
            }
            try {
                Class<? extends Annotation> aClass=annotation.annotationType();
                Method annotationMethod = aClass.getMethod("value");
                String[] value=(String[])annotationMethod.invoke(annotation);
                if(value!=null && value.length>0){
                    methodUrl=value[0];
                    break;
                }
            } catch (Exception e) {
                e.printStackTrace();
                continue;
            }


        }
        return methodUrl;

    }
}
